package HDFS_Demo;

//当前类为HDFS的连接类，实现HDFS的连接操作和HDFS的操作相关
/*
 * 如果出现权限问题报错：Permission denied
 * 那么可以通过下面几种方法解决
 * 1、添加环境变量：HADOOP_USER_NAME，root
 * 2、修改HDFS配置，在hdfs-site.xml当中加入：
    <property>
      <!-- 权限检查  -->
      <name>dfs.permissions</name>
      <value>false</value>
    </property>
 * 3、修改根目录权限，在HDFS命令行中输入：hdfs dfs -chmod -R 777 /
 */

import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.fs.FileSystem;
import org.apache.hadoop.fs.LocatedFileStatus;
import org.apache.hadoop.fs.Path;
import org.apache.hadoop.fs.RemoteIterator;
import org.apache.hadoop.io.IOUtils;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import java.io.IOException;
import java.io.InputStream;

public class Client {
    Configuration conf = null;
    FileSystem fs = null;
    @Before
    // 实现HDFS连接
    public void init() throws IOException{
        conf = new Configuration();
        conf.set("fs.defaultFS","hdfs://192.168.152.128:9000/");
        System.setProperty("HADOOP_USER_NAME","root");
        System.setProperty("HADOOP_USER_PASSWORD","hanqilong");
        fs = FileSystem.get(conf);
    }

    @Test
    // 实现在HDFS上创建一个目录
    public void createDir() throws IOException {
        fs.mkdirs(new Path("/20240813-bd/test5"));
        System.out.println("create path success");
    }

    @After
    // 关闭HDFS连接
    public void close() throws IOException {
        fs.close();
    }

    @Test
    // 上传文件
    public void putFile() throws IOException {
        //将本地文件上传到HDFS当中
        //只是单独传递文件
        //fs.copyFromLocalFile(new Path("D:\\data\\test.txt"),new Path("/20240813-bd/test1/test.txt"));
        //在传递完成之后将本地文件删除
        fs.copyFromLocalFile(true, new Path("D:\\新建文件夹\\data\\test2.txt"),
                new Path("/20240813-bd/test1/test.txt"));
    }

    @Test
    // 下载文件
    public void downloadFile() throws IOException{
        //将HDFS上的文件下载到本地
        //fs.copyToLocalFile(new Path("/20240813-bd/test1/test.txt"),new Path("D:\\data\\test.txt"));
        //在下载完成之后将HDFS上的文件删除
        fs.copyToLocalFile(true, new Path("/20240813-bd/test1/test2.txt"),
                new Path("D:\\data\\test.txt"));
        System.out.println("下载成功！！！");
    }

    @Test
    // 删除文件
    public void deleteFile() throws IOException {
        fs.delete(new Path("/20240813-bd/test1/test.txt"),true);
    }

    @Test
    //查看HDFS当中文件内容
    public void viewFile() throws IOException {
        RemoteIterator<LocatedFileStatus> status = fs.listFiles(new Path("/20240813-bd"), true);
        while (status.hasNext()) {
            LocatedFileStatus fileStatus = status.next();
            //打印文件路径
            System.out.println("文件路径为：" + fileStatus.getPath());
            //打印文件的名称
            System.out.println("文件名为：" + fileStatus.getPath().getName());
            //打印文件的权限
            System.out.println("文件的权限为：" + fileStatus.getPermission());
            //打印文件的大小
            System.out.println("文件的大小为：" + fileStatus.getLen());
            //打印文件的归属
            System.out.println("文件的所属用户：" + fileStatus.getOwner() + "文件的所属组：" + fileStatus.getGroup());
            //打印分隔符
            System.out.println("===========================================");
        }
    }

    @Test
    //查看指定文件内容
    public void printFile() throws IOException {
        //定义一个Stream输入流，接受来自于fs中读取到的文件内容
        InputStream in = fs.open(new Path("/20240813-bd/test1/test2.txt"));
        //使用IOUtils类的copyBytes方法将输入流中的内容拷贝到System.out中，拷贝的缓冲区大小为512
        IOUtils.copyBytes(in, System.out, 512);
        //关闭输入流
        IOUtils.closeStream(in);
        //in.close();
    }
}
